home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
X11
/
xpaint-2.1.1
/
fatBitsEdit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-03
|
12KB
|
468 lines
/* +-------------------------------------------------------------------+ */
/* | Copyright 1992, 1993, David Koblas (koblas@netcom.com) | */
/* | | */
/* | Permission to use, copy, modify, and to distribute this software | */
/* | and its documentation for any purpose is hereby granted without | */
/* | fee, provided that the above copyright notice appear in all | */
/* | copies and that both that copyright notice and this permission | */
/* | notice appear in supporting documentation. There is no | */
/* | representations about the suitability of this software for | */
/* | any purpose. this software is provided "as is" without express | */
/* | or implied warranty. | */
/* | | */
/* +-------------------------------------------------------------------+ */
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Toggle.h>
#include <X11/Xaw/Viewport.h>
#include <X11/Xaw/Box.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Scrollbar.h>
#include <X11/Shell.h>
#include <X11/cursorfont.h>
#include <stdio.h>
#ifndef NOSTDHDRS
#include <stdlib.h>
#include <unistd.h>
#endif
#include "Paint.h"
#include "xpaint.h"
#include "palette.h"
#include "menu.h"
#include "misc.h"
#include "cutCopyPaste.h"
#define PADDING 4
#define BW 1
typedef struct LocalInfo_s {
int curX, curY;
int offX, offY, baseX, baseY;
Widget cursor; /* The Box widget */
Widget subpaint; /* the paint widget inside the box */
Widget view; /* the widget in the popup window */
Widget paint; /* The source of this zoom */
Widget shell;
int zoom; /* paint widget zoom value */
Position spX, spY;
Dimension spBW; /* subpaint, x, y and borderwidth */
struct LocalInfo_s *next;
} LocalInfo;
static LocalInfo *head = NULL;
/*
** When the popup window is gone, free the storage
*/
static void destroyCallback(Widget w, XtPointer larg, void *junk2)
{
LocalInfo *l = (LocalInfo *)larg;
LocalInfo *c = head, **p = &head;
while (c != NULL && c != l) {
p = &c->next;
c = c->next;
}
if (c != NULL)
*p = l->next;
XtFree((XtPointer)l);
}
/*
** Done or WM-Close pressed, destroy widgets
*/
static void doneCallback(Widget w, XtPointer larg, void *junk2)
{
LocalInfo *l = (LocalInfo *)larg;
/*
** Destroy both the cursor and the popup window
*/
XtDestroyWidget(l->cursor);
XtDestroyWidget(GetShell(w));
}
/*
** Move the cursor and the view window to the position
** specified by x,y
*/
static void moveCursor(LocalInfo *l, int x, int y, int w, int h)
{
int dw, dh;
int rx, ry;
if (w == -1 || h == -1) {
int z;
Dimension wt, ht;
XtVaGetValues(l->view, XtNzoom, &z,
XtNwidth, &wt,
XtNheight, &ht,
NULL),
w = (wt + z - 1) / z;
h = (ht + z - 1) / z;
}
XtVaGetValues(l->paint, XtNdrawWidth, &dw, XtNdrawHeight, &dh, NULL);
if (x < 0) x = 0;
if (y < 0) y = 0;
if (x + w > dw) x = dw - w;
if (y + h > dh) y = dh - h;
if (x < 0 || y < 0) {
int z;
XtVaGetValues(l->view, XtNzoom, &z, NULL);
/* XXX zoom bigger than actual */
return;
}
rx = x / l->zoom;
ry = y / l->zoom;
x = rx * l->zoom;
y = ry * l->zoom;
XtVaSetValues(l->view, XtNzoomX, rx, XtNzoomY, ry, NULL);
XtVaSetValues(l->cursor, XtNx, x - l->spX - l->spBW - 1,
XtNy, y - l->spY - l->spBW - 1, NULL);
XtVaSetValues(l->subpaint, XtNzoomX, rx, XtNzoomY, ry, NULL);
}
/*
** Given the popup dimensions, set the "cursor" view to the correct size
*/
static void resizeCursor(LocalInfo *l)
{
Dimension width, height;
int zoom;
int pw,ph;
int dw,dh;
int zx,zy;
XtVaGetValues(l->view, XtNwidth, &width,
XtNheight, &height,
XtNzoom, &zoom,
NULL);
XtVaGetValues(l->paint, XtNdrawWidth, &dw,
XtNdrawHeight, &dh,
XtNzoom, &l->zoom,
NULL);
XtVaGetValues(l->subpaint, XtNzoomX, &zx,
XtNzoomY, &zy,
NULL);
pw = (width + zoom - 1) / zoom;
ph = (height + zoom - 1) / zoom;
if ((pw + zx > dw) || (ph + zy > dh)) {
int nx,ny;
nx = (pw + zx > dw) ? dw - pw : zx;
ny = (ph + zy > dh) ? dh - ph : zy;
/*
** If the new x or y value off the screen, set it back.
** and resize view
*/
if (nx < 0 || ny < 0) {
if (nx < 0) {
pw += nx;
nx = 0;
}
if (ny < 0) {
ph += ny;
ny = 0;
}
/* XXX -- this really should be SetValues(width,height)
** but that doesn't work..?/
*/
XtResizeWidget(l->view, pw * zoom, ph * zoom, 1);
}
moveCursor(l, nx, ny, pw, ph);
}
pw *= l->zoom;
ph *= l->zoom;
XtVaSetValues(l->cursor, XtNwidth, pw + 2 * (PADDING + BW),
XtNheight, ph + 2 * (PADDING + BW),
NULL);
XtVaSetValues(l->subpaint, XtNwidth, pw,
XtNheight, ph,
NULL);
}
/*
** Button down in the cursor window
*/
static void press(Widget w, LocalInfo *l, XButtonEvent *event, Boolean *flg)
{
Position x, y;
XtVaGetValues(w, XtNx, &x, XtNy, &y, NULL);
l->offX = event->x;
l->offY = event->y;
l->baseX = event->x_root - x;
l->baseY = event->y_root - y;
XtVaGetValues(l->paint, XtNzoom, &l->zoom, NULL);
}
static void motion(Widget w, LocalInfo *l, XMotionEvent *event, Boolean *flg)
{
int nx, ny;
int px, py;
/*
** Compress motion events.
*/
while (XCheckTypedWindowEvent(XtDisplay(w), XtWindow(w), MotionNotify, (XEvent*)event));
nx = event->x_root - l->baseX;
ny = event->y_root - l->baseY;
px = nx + l->spX + l->spBW + 1;
py = ny + l->spY + l->spBW + 1;
moveCursor(l, px, py, -1, -1);
}
/*
** If the paint view size changes, update the parent paint window cursor size
*/
static void sizeChanged(Widget w, LocalInfo *l, XtPointer junk)
{
resizeCursor(l);
}
/*
** The parent box widget changed size, resize to fit.
*/
static void boxChanged(Widget w, LocalInfo *l, XConfigureEvent *event, Boolean *flg)
{
Dimension width, height;
Dimension hpad, vpad, bw;
int zoom;
XtVaGetValues(l->view, XtNzoom, &zoom, XtNborderWidth, &bw,
NULL);
XtVaGetValues(XtParent(l->view), XtNwidth, &width,
XtNheight, &height,
XtNhSpace, &hpad,
XtNvSpace, &vpad,
NULL);
width -= (hpad + bw) * 2 ;
height -= (vpad + bw) * 2;
/* XXX -- this really should be SetValues(width,height)
** but that doesn't work..?/
*/
XtResizeWidget(l->view, width, height, 1);
resizeCursor(l);
}
/*
** One of the zoom perctange buttons pressed
*/
static void buttonCallback(Widget w, XtPointer lArg, void *junk2)
{
LocalInfo *l = (LocalInfo *)lArg;
char *lbl;
int nz;
int cx, cy, zx, zy, z, nw, nh;
int x, y;
Dimension width, height;
Boolean state;
XtVaGetValues(w, XtNstate, &state, XtNlabel, &lbl, NULL);
if (state == False)
return;
nz = 0;
sscanf(lbl, "%*d:%d", &nz);
if (nz == 0)
return;
XtVaGetValues(l->view, XtNzoomX, &zx,
XtNzoomY, &zy,
XtNzoom, &z,
XtNwidth, &width,
XtNheight, &height,
NULL);
cx = zx + ((width + z - 1) / z) / 2;
cy = zy + ((height + z - 1) / z) / 2;
nw = (width + nz - 1) / nz;
nh = (height + nz - 1) / nz;
XtVaSetValues(l->view, XtNzoom, nz, NULL);
/* center on image center */
x = cx - nw / 2;
y = cy - nh / 2;
moveCursor(l, x, y, width / nz, height / nz);
}
/*
** Construct the fatbits popup, and cursor
**
*/
void FatbitsEdit(Widget paint)
{
Widget shell, form, fat;
Widget button, box;
int i, zoom;
Colormap cmap;
Position x, y, lx, ly;
Dimension width = 48, height = 48;
LocalInfo *l;
static char *zoomList[] = {
"zoomButton1",
"zoomButton2",
"zoomButton3",
"zoomButton4",
"zoomButton5",
};
XtTranslations trans = XtParseTranslationTable("<BtnDown>,<BtnUp>: set() notify()");
Widget first = None;
for (l = head; l != NULL && l->paint != paint; l = l->next);
if (l != NULL) {
XMapRaised(XtDisplay(l->shell), XtWindow(l->shell));
return;
}
l = XtNew(LocalInfo);
l->paint = paint;
l->next = head;
head = l;
XtVaGetValues(paint, XtNcolormap, &cmap,
XtNzoom, &l->zoom,
XtNdownX, &lx,
XtNdownY, &ly,
NULL);
shell = XtVaCreatePopupShell("fatbits", topLevelShellWidgetClass,
GetShell(paint), XtNcolormap, cmap,
NULL);
l->shell = shell;
PaletteAddUser(PaletteFind(shell, cmap), shell);
form = XtVaCreateManagedWidget("form", formWidgetClass, shell, NULL);
box = XtVaCreateManagedWidget("fatBox", boxWidgetClass, form,
XtNbackgroundPixmap, GetBackgroundPixmap(form),
NULL);
XtAddEventHandler(box, StructureNotifyMask, False, (XtEventHandler)boxChanged, (XtPointer)l);
fat = XtVaCreateManagedWidget("paint", paintWidgetClass, box,
XtNpaint, paint,
XtNbottom, XtChainBottom,
NULL);
l->view = fat;
XtVaGetValues(fat, XtNzoom, &zoom, NULL);
XtVaSetValues(fat, XtNwidth, width * zoom,
XtNheight, height * zoom,
NULL);
button = XtVaCreateManagedWidget("done", commandWidgetClass, form,
XtNfromVert, box,
XtNtop, XtChainBottom,
XtNbottom, XtChainBottom,
XtNleft, XtChainLeft,
XtNright, XtChainLeft,
NULL);
XtAddCallback(button, XtNcallback, doneCallback, (XtPointer)l);
ccpAddStdPopup(fat);
first = None;
for (i = 0; i < XtNumber(zoomList); i++) {
button = XtVaCreateManagedWidget(zoomList[i],
toggleWidgetClass, form,
XtNfromHoriz, button,
XtNfromVert, box,
XtNtop, XtChainBottom,
XtNbottom, XtChainBottom,
XtNleft, XtChainRight,
XtNright, XtChainRight,
XtNradioGroup, first,
XtNtranslations, trans,
NULL);
first = button;
XtAddCallback(button, XtNcallback, buttonCallback, (XtPointer)l);
if (i == XtNumber(zoomList) / 2) {
XtVaSetValues(button, XtNstate, True, NULL);
}
}
XtAddCallback(shell, XtNdestroyCallback, destroyCallback, (XtPointer)l);
AddDestroyCallback(shell, (void (*)(Widget, void *, XEvent *))doneCallback, (XtPointer)l);
XtPopup(shell, XtGrabNone);
#if 0
XtVaGetValues(fat, XtNwidth, &width, XtNheight, &height, NULL);
#endif
lx -= width / 2;
ly -= height / 2;
if (lx < 0) lx = 0;
if (ly < 0) ly = 0;
x = lx - (PADDING + 2);
y = ly - (PADDING + 2);
box = XtVaCreateManagedWidget("fatBox", boxWidgetClass, paint,
XtNx, x,
XtNy, y,
XtNwidth, width + 2 * (PADDING + 1),
XtNheight, height + 2 * (PADDING + 1),
XtNborderWidth, 1,
XtNbackgroundPixmap, GetBackgroundPixmap(paint),
NULL);
l->cursor = box;
XtAddEventHandler(box, ButtonPressMask, False, (XtEventHandler)press, (XtPointer)l);
XtAddEventHandler(box, ButtonMotionMask, False, (XtEventHandler)motion, (XtPointer)l);
l->subpaint = XtVaCreateManagedWidget("fatPaint", paintWidgetClass, box,
XtNpaint, paint,
XtNzoom, PwZoomParent,
XtNx, PADDING,
XtNy, PADDING,
XtNborderWidth, 1,
XtNwidth, width,
XtNheight, height,
XtVaTypedArg, XtNcursor, XtRString, "fleur", sizeof(Cursor),
NULL);
XtAddCallback(l->view, XtNsizeChanged, (XtCallbackProc)sizeChanged, (XtPointer)l);
XtVaGetValues(l->subpaint, XtNx, &l->spX,
XtNy, &l->spY,
XtNborderWidth, &l->spBW,
NULL);
XtVaSetValues(l->subpaint, XtNzoomX, lx, XtNzoomY, ly, NULL);
XtVaSetValues(l->view, XtNzoomX, lx, XtNzoomY, ly, NULL);
/*
** Set the current operator
*/
GraphicAdd(fat);
StateAddParent(shell, paint);
}